/* ************************************
 * GazeVis
 * 
 * ************************************
 */

// Subject data
// =============================================

// what directory to load?
String subject_directory			= "subject13";
String tree_directory			= "trees_full";
String experiment_file			= "experiment_stimuli_FULL.txt";
String settings_file			= "settings.txt";
boolean write_heatmaps			= false;
boolean draw_lines			= true;
boolean summarize_data			= true;

boolean plot                = false;

// control variable
float timeScale = 1.0;


// data
SubjectLog subjectLog = null;





// constants
// ==================
//static final int VIS_WIDTH		= 1280;
//static final int VIS_HEIGHT		= 800;

static final int VIS_WIDTH		= 1280;
static final int VIS_HEIGHT		= 1024;
static final int GUI_HEIGHT		= 100;

static final int BUFFER_SIZE		= 1024*1024*5;
static final color HILIGHT_COLOR	= #FF8686;


// global variables
// ====================
int maxChild = -1;
int treeDepth = -1;
int lastMillis = 0;

Timeline gazeTimeline = null;
Timeline visTimeline = null;

// timeline and sliders
boolean gazeTimelineHeld = false;
boolean visTimelineHeld = false;
boolean globalPlay = false;
boolean slidersSynched = false;

// heatmaps
HashMap< Integer, Heatmap> heatmaps = null;

// returns current time in seconds and fractions of it
float getTime()
{
	return (float) millis() / 1000.0;
}

void setup()
{
	size(VIS_WIDTH, VIS_HEIGHT + GUI_HEIGHT);
	smooth();
	
	// load subject log
	println("Loading data in " + subject_directory);
	subjectLog = new SubjectLog( experiment_file, subject_directory );
	
	// create user interface
	gazeTimeline = new Timeline( 
		subjectLog.getGazeData().getLastTimestamp(), 
		TIMELINE_GAZE_X_OFFSET, TIMELINE_GAZE_Y_OFFSET );
		
	visTimeline = new Timeline(
		subjectLog.getVisData().getLastTimestamp(),
		TIMELINE_VIS_X_OFFSET, TIMELINE_VIS_Y_OFFSET );
		
	subjectLog.loadSettings();
}

void draw()
{
	// calculate delta millis
	int m = millis();
	int delta = m - lastMillis;
	lastMillis = m;
	
	background( 50);
	
	// render gaze data
	subjectLog.render( delta );

	gazeTimeline.setState( subjectLog.getGazePlayState() );
	visTimeline.setState( subjectLog.getVisPlayState() );

	// render interface background
	noStroke();
	fill(0);
	rect( 0, VIS_HEIGHT, VIS_WIDTH, GUI_HEIGHT );
	
	// render gaze timeline
	gazeTimeline.setCurrentT( subjectLog.gazeVis.getCurrentT() );
	visTimeline.setCurrentT( subjectLog.vis.getCurrentT() );
	
	gazeTimeline.render();
	visTimeline.render();
}

void mousePressed()
{
	if (
		(mouseX >= TIMELINE_GAZE_X_OFFSET && mouseX <= TIMELINE_GAZE_X_OFFSET + 30 + TIMELINE_WIDTH) &&
		(mouseY >= TIMELINE_GAZE_Y_OFFSET - 5 && mouseY <= TIMELINE_GAZE_Y_OFFSET + 5)
	)
	{
		if (gazeTimeline.mousePressed())
		{
			gazeTimelineHeld = true;	
		}
		int state = gazeTimeline.getState();
		subjectLog.setGazePlayState( state );
		
		if (slidersSynched) {
			visTimeline.setState( state );
			subjectLog.setVisPlayState( state );
			globalPlay = state == STATE_PLAYING;
		}
	}
	
	else if (
		(mouseX >= TIMELINE_VIS_X_OFFSET && mouseX <= TIMELINE_VIS_X_OFFSET + 30 + TIMELINE_WIDTH) &&
		(mouseY >= TIMELINE_VIS_Y_OFFSET - 5 && mouseY <= TIMELINE_VIS_Y_OFFSET + 5)
	)
	{
		if (visTimeline.mousePressed())
		{
			visTimelineHeld = true;	
		}
		int state = visTimeline.getState();
		subjectLog.setVisPlayState( state );
		
		if (slidersSynched) {
			gazeTimeline.setState( state );
			subjectLog.setGazePlayState( state );
			globalPlay = state == STATE_PLAYING;
			
		}
		
	}	
}

void mouseReleased()
{
	if (gazeTimelineHeld)
	{
		gazeTimeline.mouseReleased();
		gazeTimelineHeld = false;
	}
	else if (visTimelineHeld)
	{
		visTimeline.mouseReleased();
		visTimelineHeld = false;
	}	
}

void mouseDragged()
{
	if (gazeTimelineHeld) 
	{
		gazeTimeline.mouseDragged();
		subjectLog.updateGazeT( gazeTimeline.getCurrentT() );
		
		if (slidersSynched) {
			visTimeline.setCurrentT( gazeTimeline.getCurrentT() - gazeTimeline.lowLimit );
			subjectLog.updateVisT( visTimeline.getCurrentT() );
		}
	}
	
	else if (visTimelineHeld)
	{
		visTimeline.mouseDragged();
		subjectLog.updateVisT( visTimeline.getCurrentT() );
		
		if (slidersSynched) {
			gazeTimeline.setCurrentT( visTimeline.getCurrentT() + gazeTimeline.lowLimit );
			subjectLog.updateGazeT( gazeTimeline.getCurrentT() );
		}
	}
}

void keyPressed()
{
	if (key == ' ')
	{
		// play both timelines
		subjectLog.playBoth();	
	}
	
	else if (key == 's' || key == 'S')
	{
		subjectLog.sync();
	}
	else if (key == 'u' || key == 'U')
	{
		subjectLog.unsync();
	}
	else if (key == 'c' || key == 'C')
	{
		println("\nChopping files...");
		subjectLog.chopFiles();
		println("\n");
	}
	else if (key == 'l' || key == 'L')
	{
		draw_lines = !draw_lines;
	}
    else if (key == 'p' || key == 'P')
    {
        plot = !plot;
        draw_lines = !plot;
    }
	
	// left / right arrows
	else if (key == CODED)
	{
		boolean update = false;
		if (keyCode == RIGHT)
		{
			update = true;
			//gazeTimeline.increment();
			subjectLog.jumpToNextFixation();
		}
		else if (keyCode == LEFT)
		{
			update = true;
			//gazeTimeline.decrement();
			subjectLog.jumpToPreviousFixation();
		}
		
		/*
		if (update)
		{
			subjectLog.updateGazeT( gazeTimeline.getCurrentT() );
		
			if (slidersSynched)
			{
				visTimeline.setCurrentT( gazeTimeline.getCurrentT() - gazeTimeline.lowLimit );
				subjectLog.updateVisT( visTimeline.getCurrentT() );
			}
		}
		*/
	}
}

